package core.models;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.util.AbstractList;
import java.util.HashMap;
import java.util.List;
import java.util.Map.Entry;
import java.util.Scanner;

import javax.swing.ComboBoxModel;
import javax.swing.DefaultListModel;

import org.apache.commons.lang3.StringUtils;

public class DhcpConfiguration extends DefaultListModel implements ComboBoxModel {

	/**
	 * 
	 */
	private static final long serialVersionUID = -1863296351401216819L;
	private HashMap<String, String> options;
	private List<DhcpSubnet> subnets;

	/**
	 * regex
	 */
//	private static final String COMMENT_REGEX = "^\\s*#.*";
//	private static final String DDNS_UPDATE_STYLE_REGEX = "^\\s*dns-update-style\\s+\\w+;\\s*";
//	private static final String LEASE_TIME_REGEX = "^\\s*((default)|(max))-lease-time\\s+\\d+;\\s*";
//	private static final String LOGFACILITY_REGEX = "^\\s*log-facility\\s+\\w+;\\s*";
	private static final String SUBNET_REGEX = "^\\s*subnet\\s+\\b\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\b\\s+netmask\\s+\\b\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\b\\s+\\{\\s*";
	private static final String OPTION_REGEX = "^\\s*((option\\s+)?[\\w\\-]+)\\s+(.+);\\s*";
	private static final String MNGRHEADER = "### ROUTER MANAGER GENERATED CONTENT ###";

	
	private Object currentValue;

	public DhcpConfiguration() {
		options = new HashMap<String, String>();
		subnets = new AbstractList<DhcpSubnet>() {
			@Override
			public DhcpSubnet get(int index) {
				return (DhcpSubnet) getElementAt(index);
			}

			@Override
			public int size() {
				return getSize();
			}
		};
	}

	public void loadConfiguration(File file) throws FileNotFoundException {
		Scanner scanner = new Scanner(file);
		while (scanner.hasNextLine()) {
			String line = scanner.nextLine();
			if (line.matches(OPTION_REGEX)) {
				String[] option = line.trim().split("\\s+");
				if (option[0].equals("option")) {
					options.put(option[0] + " " + option[1], StringUtils.chop(StringUtils.join(option, " ", 2, option.length)));
				} else {
					options.put(option[0], StringUtils.chop(StringUtils.join(option, " ", 1, option.length)));
				}
			} else if (line.matches(SUBNET_REGEX)) {
				String[] subnetOptions = line.trim().split("\\s+");
				DhcpSubnet subnet = new DhcpSubnet(subnetOptions[1],
						subnetOptions[3]);
				subnet.processConfig(scanner);
				addElement(subnet);
			}
		}
	}
	
	public File generateDhcpdConf() throws IOException {
		File file = File.createTempFile("RtrMngrTmp",
				Long.toString(System.currentTimeMillis()));
		file.deleteOnExit();
		BufferedWriter out = new BufferedWriter(new FileWriter(file));
		
		// Header
		out.append(MNGRHEADER);
		out.append("\n\n");
		
		// Options
		for (Entry<String, String> entry : options.entrySet()) {
			out.append(entry.getKey());
			out.append(" ");
			out.append(entry.getValue());
			out.append(";\n");
		}
		
		out.append("\n");
		
		for (DhcpSubnet subnet : subnets) {
			out.append(subnet.toConfigFormat());
		}
		
		out.close();
		return file;
	}
	
	public static String[] getAvailableDdnsUpdatesStyles() {
		String[] result = {"none", "ad-hoc", "interim"};
		return result;
	}

	public HashMap<String, String> getOptions() {
		return options;
	}

	public void setOptions(HashMap<String, String> options) {
		this.options = options;
	}

	@Override
	public Object getSelectedItem() {
		return currentValue;
	}

	@Override
	public void setSelectedItem(Object anItem) {
		currentValue = anItem;
		fireContentsChanged(this, -1, -1);
	}
	
	
}
